package com.mmall.filter;

import com.mmall.common.RequestHolder;
import com.mmall.model.SysUser;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 登录拦截请求
 */
@Slf4j
public class LoginFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    /**
     * 注意 任何一次请求都会调用该方法
     * 该方法会相继调用到 controller层 service层 。。。直到请求结束返回 --> 为一条线程
     * 方法中的sysUser与req被临时的缓存下来，在并发中会被其他线程篡改
     * 为了防止缓存对象被其他线程篡改的情况同时保证其他线程不被阻塞
     * 在RequestHolder中的对象通过ThreadLocal封装起来
     */
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        //浏览器中会有一个sessionId req.getSession 可以从中获取 服务端的 session 对象
        // 从session 获取当前用户
        SysUser sysUser = (SysUser)req.getSession().getAttribute("user");
        //如果当前用户为空 说明该客户端（浏览器）没有进行过登录
        if (sysUser == null) {
            String path = "/signin.jsp";
            resp.sendRedirect(path); //重定向至 signin.jsp 页面
            return;
        }
        //缓存当前用户信息
        RequestHolder.add(sysUser);
        //缓存当前请求信息
        RequestHolder.add(req);
        filterChain.doFilter(servletRequest, servletResponse);
        return;
    }

    public void destroy() {

    }
}
